package com.games.ecoship.server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;

import com.games.ecoship.EcoShipConstants;

public class HandleASession implements EcoShipConstants, Runnable {

	// Players
	private Socket player1;
	private Socket player2;
	
	// Game cells
	private char[][] player1Board = new char[NUM_COLS][NUM_ROWS];
	private char[][] player2Board = new char[NUM_COLS][NUM_ROWS];
	
	// Server Communication
	private DataInputStream  fromPlayer1;
	private DataOutputStream toPlayer1;
	private DataInputStream  fromPlayer2;
	private DataOutputStream toPlayer2;
	
	// Game Running
	private Boolean continueToPlay = true;
	
	public HandleASession(Socket player1, Socket player2) {
		this.player1 = player1;
		this.player2 = player2;
		
		// Init cells in both player boards
		for (int cols=0; cols < NUM_COLS; cols++) {
			for (int rows=0; rows < NUM_ROWS; rows++) {
				player1Board[cols][rows] = EMPTY_SPOT;
				player2Board[cols][rows] = EMPTY_SPOT;
			}
		}
	}

	@Override
	public void run() {
		try {
			// Init input and output streams
			fromPlayer1 = new DataInputStream(player1.getInputStream());
			toPlayer1   = new DataOutputStream(player1.getOutputStream());
			fromPlayer2 = new DataInputStream(player2.getInputStream());
			toPlayer2   = new DataOutputStream(player2.getOutputStream());
			
			// Write something to notify player 1 to start
			toPlayer1.writeInt(PLAYER1);
			
			// Wait for both players to finish setting up their boards
			waitForSetup();
			
			// Setup the server model of the game; prepares the determining of game state
			recieveBoardInfo();
			
			// Game loop, in which the server is the intermediary sends info to
			// both players, and notifies them what the status of the game is).
			while (continueToPlay) {
				
				// Player 1 takes a turn, and game logic applied
				takeTurn(fromPlayer1, toPlayer1, toPlayer2);
				
				// Player 2 takes a turn, and game logic applied
				takeTurn(fromPlayer2, toPlayer2, toPlayer1);
				
			}
		}
		catch(IOException ex) {
			System.out.println(ex);
		}
	}

	private void waitForSetup() throws IOException {
		// Reads anything, first from player 1, then from player 2, to indicate that both
		// are done setting up their boards.
		fromPlayer1.readInt();
		fromPlayer2.readInt();
	}

	/**
	 * Requests the information about where each player placed their units. The
	 * server model of the game is then setup accoringly.
	 * 
	 * @throws IOException
	 */
	private void recieveBoardInfo() throws IOException {
		
		for (int cols=0; cols < NUM_COLS; cols++) {
			for (int rows=0; rows < NUM_ROWS; rows++) {
				player1Board[cols][rows] = fromPlayer1.readChar();
				player2Board[cols][rows] = fromPlayer2.readChar();
			}
		}
		
		// TESTING
		displayServerBoards();
	}

	/**
	 * Used only for testing purposes. Prints out both player's boards.
	 */
	private void displayServerBoards() {
		ArrayList<char[][]> players = new ArrayList<char[][]>();
		players.add(player1Board);
		players.add(player2Board);
		for (int player=0; player < players.size(); player++) {
			System.out.println("Player " + (player+1) + "'s Board:");
			for (int rows=0; rows < NUM_ROWS; rows++) {
				for (int cols=0; cols < NUM_COLS; cols++) {
					System.out.print((char)players.get(player)[cols][rows] + " ");
				}
				System.out.println();
			}
			System.out.println('\n');
		}
	}

	/**
	 * Player 1 and player 2 alternate taking turns using this function, and all
	 * game logic is carried out here.
	 * 
	 * @param fromP1
	 * @param toP1
	 * @param toP2
	 * @throws IOException
	 */
	private void takeTurn(DataInputStream fromP1, DataOutputStream toP1, DataOutputStream toP2) throws IOException {
		
		// Recieve move from p1 (column, then row submitted)
		int col = fromP1.readInt();
		int row = fromP1.readInt();
		//if (fromP1 == fromPlayer1)
			//board[col][row] = 'X';
		//else
			//board[col][row] = 'O';
		
		// Check if p1 has won, and inform p2
		/*if (isWinner(PLAYER1)) {
			toP1.writeInt(PLAYER1_WON);
			toP2.writeInt(PLAYER1_WON);
			continueToPlay = false;
		}
		// Check if p1 has won, and inform p2
		else if (isWinner(PLAYER2)) {
			toP1.writeInt(PLAYER2_WON);
			toP2.writeInt(PLAYER2_WON);
			continueToPlay = false;
		}
		// Check to see if all cells in the board are filled
		else if (isFull()) {
			toP1.writeInt(DRAW);
			toP2.writeInt(DRAW);
			continueToPlay = false;
		}
		// Game continues
		else {
			//Notify p2 to take a turn
			toP2.writeInt(CONTINUE);
		}
		
		// Send p1's move to p2
		sendMove(toP2, col, row);*/
	}
}
